/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						script_creatures_in_army.cpp

	$Header: /heroes4/script_creatures_in_army.cpp $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "script_creatures_in_army.h"

#include "creature.h"
#include "creature_array.h"
#include "creature_type.h"
#include "sized_int_types.h"
#include "script_targeting.h"
#include "streambuf_operators.h"

// --------------------------------------------------------------------------
// t_script_creatures_in_army members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
t_script_creatures_in_army::t_result 
t_script_creatures_in_army::evaluate(t_expression_context_hero const& context) const
{
	t_creature_array const* array = select_army_by_target(get_target(), NULL, context.army, context.opposing_army);
	return do_evaluate(array);
}

t_script_creatures_in_army::t_result 
t_script_creatures_in_army::evaluate(t_expression_context_town const& context) const
{
	t_creature_array const* array = select_army_by_target(get_target(), context.garrison, NULL, context.opposing_army);
	return do_evaluate(array);
}

t_script_creatures_in_army::t_result 
t_script_creatures_in_army::evaluate(t_expression_context_object const& context) const
{
	assert(false);
	return 0;
}

t_script_creatures_in_army::t_result 
t_script_creatures_in_army::evaluate(t_expression_context_army const& context) const
{
	t_creature_array const* array = select_army_by_target(get_target(), NULL, context.army, context.opposing_army);
	return do_evaluate(array);
}

t_script_creatures_in_army::t_result 
t_script_creatures_in_army::evaluate(t_expression_context_global const& context) const
{
	assert(false);
	return 0;
}

t_script_creatures_in_army::t_result 
t_script_creatures_in_army::do_evaluate(t_creature_array const* array) const
{
	int creature_count = 0;
	if (array) 
	{
		for (int i = 0; i < t_creature_array::k_size; i++) 
		{
			t_creature const* creature = (*array)[i].get_creature();
			if (creature && (creature->get_creature_type() == get_creature_type()))
				creature_count += creature->get_number();
		}
	}
	return creature_count;
}


// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_script_creatures_in_army::read_from_map(
	std::streambuf &	stream,
	int					format_version )
{
	if ( !t_script_targeted_numeric_expression< t_target >::read_from_map( stream, format_version ) )
		return false;

	m_creature_type = t_creature_type( get< t_uint16 >( stream ) );
	return m_creature_type >= 0 && m_creature_type < k_creature_type_count;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_script_creatures_in_army::read( std::streambuf& stream, int version )
{
	if ( !t_script_targeted_numeric_expression< t_target >::read( stream, version ) )
		return false;

	m_creature_type = get< t_creature_type >( stream );
	
	return true;
}

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
bool t_script_creatures_in_army::write( std::streambuf& stream ) const
{
	if ( !t_script_targeted_numeric_expression< t_target >::write( stream ) )
		return false;

	put< t_creature_type >( stream, m_creature_type );
	
	return true;
}

// --------------------------------------------------------------------------
// t_script_total_creatures_in_army members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
t_script_total_creatures_in_army::t_result 
t_script_total_creatures_in_army::evaluate(t_expression_context_hero const& context) const
{
	t_creature_array const* array = select_army_by_target(get_target(), NULL, context.army, context.opposing_army);
	return do_evaluate(array);
}

t_script_total_creatures_in_army::t_result 
t_script_total_creatures_in_army::evaluate(t_expression_context_town const& context) const
{
	t_creature_array const* array = select_army_by_target(get_target(), context.garrison, NULL, context.opposing_army);
	return do_evaluate(array);

}

t_script_total_creatures_in_army::t_result 
t_script_total_creatures_in_army::evaluate(t_expression_context_object const& context) const
{
	assert(false);
	return 0;
}

t_script_total_creatures_in_army::t_result 
t_script_total_creatures_in_army::evaluate(t_expression_context_army const& context) const
{
	t_creature_array const* array = select_army_by_target(get_target(), NULL, context.army, context.opposing_army);
	return do_evaluate(array);
}

t_script_total_creatures_in_army::t_result 
t_script_total_creatures_in_army::evaluate(t_expression_context_global const& context) const
{
	assert(false);
	return 0;
}

t_script_total_creatures_in_army::t_result
t_script_total_creatures_in_army::do_evaluate( t_creature_array const* array ) const
{
	int creature_count = 0;
	if (array) 
	{
		for (int i = 0; i < t_creature_array::k_size; i++) 
		{
			t_creature const* creature = (*array)[i].get_const_creature();
			if (creature) 
				creature_count += creature->get_number();
		}
	}
	return creature_count;
}

// --------------------------------------------------------------------------
// t_script_total_heroes_in_army members
// --------------------------------------------------------------------------

// --------------------------------------------------------------------------
// --------------------------------------------------------------------------

t_script_total_heroes_in_army::t_result 
t_script_total_heroes_in_army::evaluate(t_expression_context_hero const& context) const
{
	t_creature_array const* array = select_army_by_target(get_target(), NULL, context.army, context.opposing_army);
	return do_evaluate(array);
}

t_script_total_heroes_in_army::t_result 
t_script_total_heroes_in_army::evaluate(t_expression_context_town const& context) const
{
	t_creature_array const* array = select_army_by_target(get_target(), context.garrison, NULL, context.opposing_army);
	return do_evaluate(array);

}

t_script_total_heroes_in_army::t_result 
t_script_total_heroes_in_army::evaluate(t_expression_context_object const& context) const
{
	assert(false);
	return 0;
}

t_script_total_heroes_in_army::t_result 
t_script_total_heroes_in_army::evaluate(t_expression_context_army const& context) const
{
	t_creature_array const* array = select_army_by_target(get_target(), NULL, context.army, context.opposing_army);
	return do_evaluate(array);
}

t_script_total_heroes_in_army::t_result 
t_script_total_heroes_in_army::evaluate(t_expression_context_global const& context) const
{
	assert(false);
	return 0;
}

t_script_total_heroes_in_army::t_result
t_script_total_heroes_in_army::do_evaluate( t_creature_array const* array ) const
{
	int hero_count = 0;
	if (array) 
	{
		for (int i = 0; i < t_creature_array::k_size; i++) 
		{
			t_hero const* hero = (*array)[i].get_const_hero();
			if (hero) 
				hero_count++;
		}
	}
	return hero_count;
}
